package acc_controllers

import (
	"chat-room/providers"
	"chat-room/websocket/acc_service"
	"github.com/gorilla/websocket"
)

var (
	newline = []byte{'\n'}
	//space   = []byte{'<','b','r','>'}
	space = []byte{'\n'}
)

/**
 * @Author: yang
 * @Description：client连接对象
 * @Date: 2021/10/28 18:02
 */
type Client struct {
	Addr          string          // 客户端地址
	Socket        *websocket.Conn // 用户连接
	Send          chan []byte     // 待发送的数据
	UserToken     string          // 用户Token
	FirstTime     uint64          // 首次连接事件
	HeartbeatTime uint64          // 用户上次心跳时间
}

func NewClient(addr string, socket *websocket.Conn, firstTime uint64, token string) (cli *Client) {
	cli = &Client{
		Addr:          addr,
		Socket:        socket,
		Send:          make(chan []byte, 150), // 信息堆积
		FirstTime:     firstTime,
		HeartbeatTime: firstTime,
		UserToken:     token,
	}
	return
}

/**
 * @Author: yang
 * @Description：读取信息
 * @Date: 2021/10/28 19:10
 */
func (c *Client) ReadMsg() {
	defer func() {
		// @Todo 注銷client连接
		clientManger.Unregister <- c
		c.Socket.Close()
	}()

	for {
		// 读取信息（断开连接时候，err 会报错）
		_, msg, err := c.Socket.ReadMessage()
		if err != nil {
			//如果以意料之外的关闭状态关闭
			if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway, websocket.CloseAbnormalClosure) {
			_:
				providers.Logger.Error("websocket 连接非正常断开", err, c.Addr, c.UserToken)
			}
			break
		} else {
			if string(msg) != "" {
				// 消息入库
				logService := new(acc_service.LogService)
				err := logService.SaveLog(string(msg), c.UserToken, 1)
				if err != nil {
				_:
					providers.Logger.Error("聊天记录入库失败", err)
				}

				// 信息序列化（json）
				sendJson := logService.ProductLog(string(msg), c.UserToken, 2)

				// 推送本房间内所有人
				userService := new(acc_service.UserService)
				userTokenList := userService.GetUserTokenList(c.UserToken)
				if userTokenList != nil {
					clientManger.Broadcast <- &BroadcastMsg{
						UserTokens: userTokenList,
						Msg:        []byte(sendJson),
					}
				}
			}
		}
	}
}

/**
 * @Author: yang
 * @Description：推送信息
 * @Date: 2021/10/28 19:10
 */
func (c *Client) WriteMsg() {
	defer func() {
		c.Socket.Close()
	}()

	for {
		select {
		case msg, ok := <-c.Send:

			// 管道已经关闭
			if !ok {
				// 通知客戶端关闭
			_:
				c.Socket.WriteMessage(websocket.CloseMessage, []byte{})
				return
			}
			w, err := c.Socket.NextWriter(websocket.TextMessage)
			if err != nil {
				return
			}
			w.Write(msg)

			n := len(c.Send)
			for i := 0; i < n; i++ {
				w.Write(newline)
				w.Write(<-c.Send)
			}
			//客户端关闭，退出
			if err := w.Close(); err != nil {
				return
			}
		}
	}
}
